package com.hko.qrip.service.impl;

import it.sauronsoftware.ftp4j.FTPFile;

import java.io.File;
import java.io.FilenameFilter;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Scanner;

import org.springframework.beans.factory.annotation.Autowired;

import com.hko.qrip.bean.SubWarn;
import com.hko.qrip.dao.FtpLogDao;
import com.hko.qrip.dao.SubWarnDao;
import com.hko.qrip.manager.FTPManager;
import com.hko.qrip.service.SubWarnService;
import com.hko.qrip.util.QripJobOptions;

public class SubWarnServiceImpl implements SubWarnService {

	private static String TIMEROW = "ISSUE TIME:";
	private static String TURB = "TURB";
	private static String MOD_TURB = "MOD";
	private static String SEV_TURB = "SEV";
	private static String MICROBURST = "MBST";
	private static String WINDSHEAR = "WS";

	@Autowired
	private QripJobOptions jobOptions;

	@Autowired
	private SubWarnDao subWarnDao;

	@Autowired
	private FtpLogDao ftpLogDao;

	@Override
	public int insertAlert(SubWarn alert) throws SQLException {
		return subWarnDao.insertAlert(alert);
	}

	@Override
	public int insertTurbAlert(SubWarn alert) throws SQLException {
		return subWarnDao.insertTurbAlert(alert);
	}

	@Override
	public void doSync() throws Exception {
		System.out.println("[INFO] SubWarn sync service started");

		downloadAlertFile();
		File lrDir = new File(jobOptions.getLocalFilePath());
		File[] lrFiles = lrDir.listFiles(new FilenameFilter() {
			@Override
			public boolean accept(File arg0, String arg1) {
				if (arg1.contains("subwarn")) {
					return true;
				}
				return false;
			}
		});

		for (File file : lrFiles) {
			ArrayList<SubWarn> alerts = getAlertFile(file);
			int changeCount = 0;
			for (SubWarn alert : alerts) {
				if (alert.isTurb()) {
					changeCount += insertTurbAlert(alert);
				} else {
					changeCount += insertAlert(alert);
				}
			}
			System.out.println(changeCount + " alerts inserted");
			ftpLogDao.insertTableLog(file.getName(), changeCount, alerts.size(), "");
			file.delete();
		}
		System.out.println("[INFO] SubWarn sync service ended");

	}

	private void downloadAlertFile() throws Exception {
		FTPManager fm = new FTPManager(jobOptions.getFtpHost(), jobOptions.getFtpUser(), jobOptions.getFtpPassword());
		fm.ftpLogin();
		fm.changeDir(jobOptions.getFtpPath());
		FTPFile[] files = fm.listFiles("subwarn*");
		for (FTPFile file : files) {
			fm.downloadAndDeleteFile(jobOptions.getLocalFilePath() + file.getName(), file.getName());
			System.out.println("downloaded: " + file.getName());
			ftpLogDao.insertFtpLog(file.getName());
		}
		fm.close();
	}

	private ArrayList<SubWarn> getAlertFile(File file) throws Exception {
		ArrayList<SubWarn> resultList = new ArrayList<SubWarn>();

		Scanner fin = new Scanner(file);
		Timestamp lineTs = new Timestamp(0L);
		while (fin.hasNextLine()) {
			String line = fin.nextLine().trim();
			if (line.contains(TIMEROW)) {
				Date date = new SimpleDateFormat("dd/MM/yyyy HH:mm").parse(line.substring(12));
				lineTs = new Timestamp(date.getTime());
			} else {
				if (line.contains(TURB)) {
					SubWarn alert = new SubWarn();
					alert.setDatetime(lineTs);
					alert.setCorridor(line.substring(0, 5).replace(" ", ""));
					alert.setTurb(true);
					if (line.contains(SEV_TURB)) {
						alert.setMagnitude(3);
					} else if (line.contains(MOD_TURB)) {
						alert.setMagnitude(2);
					} else
						alert.setMagnitude(1);
					if (!resultList.contains(alert)) {
						resultList.add(alert);
					}
				}
				if (line.contains(WINDSHEAR)) {
					SubWarn alert = new SubWarn();
					alert.setDatetime(lineTs);
					alert.setCorridor(line.substring(0, 5).replace(" ", ""));
					if (line.contains(MICROBURST)) {
						alert.setIsMba(1);
					}
					if (!resultList.contains(alert)) {
						resultList.add(alert);
					}
				}
			}
		}
		fin.close();

		return resultList;
	}

}
